home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 2002 #3
/
Amiga Plus CD - 2002 - No. 03.iso
/
AmiSoft
/
Dev
/
Mui
/
Mcc_speedbar.lha
/
MCC_SpeedBar
/
Developer
/
C
/
Examples
/
barclass.c
next >
Wrap
C/C++ Source or Header
|
2002-12-21
|
11KB
|
391 lines
#include "barclass.h"
/***********************************************************************/
#define BOOLSAME(a,b) (((a) ? TRUE : FALSE)==((b) ? TRUE : FALSE))
/***********************************************************************/
/*
** Utilility functions
*/
static ULONG STDARGS
DoSuperNew(struct IClass *cl,Object *obj,ULONG tag1,...)
{
return DoSuperMethod(cl,obj,OM_NEW,&tag1,NULL);
}
/***********************************************************************/
/*
** Bar Class data
*/
struct special
{
ULONG exclude;
ULONG flags;
};
enum
{
SFLG_Skip = 1<<0,
SFLG_Disabled = 1<<1,
};
struct data
{
struct special *specials;
ULONG nb;
ULONG active;
ULONG flags;
};
enum
{
FLG_Disabled = 1<<0,
};
/***********************************************************************/
/*
** Bar Class New method
*/
static ASM ULONG
mNew(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct opSet *msg)
{
register struct SBButton *source, *s;
register struct MUIS_SpeedBar_Button *buttons;
register struct special *specials;
register struct TagItem *attrs = msg->ops_AttrList;
register STRPTR *pics;
register int nb, i, j;
/* First sanity check */
if (!(source = (struct SBButton *)GetTagData(MUIA_Bar_Buttons,NULL,attrs)))
return 0;
/* Counts buttons */
for (nb = 1, s = source; s->file!=(STRPTR)MUIV_SpeedBar_End; s++, nb++);
/* Alloc buttons, specials and pics */
if (!(buttons = AllocVec((sizeof(STRPTR)+sizeof(struct MUIS_SpeedBar_Button))*nb,MEMF_ANY|MEMF_CLEAR)) ||
!(specials = AllocVec(sizeof(struct special)*nb,MEMF_ANY|MEMF_CLEAR)))
{
if (buttons) FreeVec(buttons);
return 0;
}
pics = (STRPTR *)((UBYTE *)buttons+sizeof(struct MUIS_SpeedBar_Button)*nb);
/* Fill structures */
for (i = j = 0, s = source; i<nb; i++)
{
if (s[i].file==(STRPTR)MUIV_SpeedBar_Spacer)
{
buttons[i].Img = MUIV_SpeedBar_Spacer;
specials[i].flags |= SFLG_Skip;
continue;
}
if (s[i].file==(STRPTR)MUIV_SpeedBar_End)
{
buttons[i].Img = MUIV_SpeedBar_End;
continue;
}
pics[j] = s[i].file;
buttons[i].Img = j++;
buttons[i].Text = s[i].text;
buttons[i].Help = s[i].help;
buttons[i].Flags = s[i].flags;
if (specials[i].exclude = s[i].exclude)
{
buttons[i].Flags |= MUIV_SpeedBar_ButtonFlag_Immediate;
buttons[i].Flags &= ~MUIV_SpeedBar_ButtonFlag_Toggle;
}
}
/* Create the bar */
if (obj = (Object *)DoSuperNew(cl,obj,
MUIA_Group_Horiz, TRUE,
MUIA_SpeedBar_Buttons, buttons,
MUIA_SpeedBar_Pics, pics,
MUIA_SpeedBar_StripUnderscore, TRUE,
MUIA_SpeedBar_EnableUnderscore, TRUE,
MUIA_SpeedBar_SpacerIndex, -1,
TAG_MORE,attrs))
{
register struct data *data = INST_DATA(cl,obj);
register ULONG sel = -1;
data->nb = nb;
data->specials = specials;
data->active = -1;
/* Set up mutual exclude notifications */
for (i = 0; i<nb; i++)
{
if (specials[i].exclude)
{
DoMethod(buttons[i].Object,MUIM_Notify,MUIA_Selected,TRUE,obj,2,MUIM_Bar_Active,i);
if (buttons[i].Flags & MUIV_SpeedBar_ButtonFlag_Selected) sel = i;
}
}
if (sel>=0) nfset(obj,MUIA_Bar_Active,sel);
}
else FreeVec(specials);
/* Buttons is not needed anymore */
FreeVec(buttons);
return (ULONG)obj;
}
/***********************************************************************/
/*
** Bar Class OM_GET
*/
static ASM ULONG
mGet(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct opGet *msg)
{
register struct data *data = INST_DATA(cl,obj);
switch (msg->opg_AttrID)
{
case MUIA_Bar_Active: *msg->opg_Storage = data->active; return TRUE;
default: return DoSuperMethodA(cl,obj,(Msg)msg);
}
}
/***********************************************************************/
/*
** Bar Class OM_SET method
*/
static ASM ULONG
mSets(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct opSet *msg)
{
register struct data *data = INST_DATA(cl,obj);
register struct TagItem *tag;
struct TagItem *tstate;
register ULONG nb = data->nb;
for (tstate = msg->ops_AttrList; tag = NextTagItem(&tstate); )
{
register ULONG tidata = tag->ti_Data;
switch(tag->ti_Tag)
{
case MUIA_Bar_Active:
{
register struct data *data = INST_DATA(cl,obj);
register ULONG button = tidata, exclude;
register Object *o;
register int i;
if (data->active==button || button<0 || button>nb-1 || !(exclude = data->specials[button].exclude))
{
tag->ti_Tag = TAG_IGNORE;
break;
}
data->active = button;
o = (Object *)DoSuperMethod(cl,obj,MUIM_SpeedBar_GetObject,button);
set(o,MUIA_Selected,TRUE);
for (i = 0; i<nb; i++)
if (exclude & (1<<i))
{
register Object *oo = (Object *)DoSuperMethod(cl,obj,MUIM_SpeedBar_GetObject,i);
ULONG sel;
get(oo,MUIA_Selected,&sel);
if (sel) set(oo,MUIA_Selected,FALSE);
}
break;
}
}
}
return DoSuperMethodA(cl,obj,(Msg)msg);
}
/***********************************************************************/
/*
** Bar Class OM_DISPOSE method
*/
static ASM ULONG
mDispose(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
{
register struct data *data = INST_DATA(cl,obj);
FreeVec(data->specials);
return DoSuperMethodA(cl,obj,msg);
}
/***********************************************************************/
/*
** Bar Class MUIM_Bar_Set method
*/
static ASM ULONG
mBarSet(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct MUIP_Bar_Set *msg)
{
register struct data *data = INST_DATA(cl,obj);
register ULONG button = msg->button;
register Object *o;
register ULONG tag, value;
if (button>=data->nb) return 0;
o = (Object *)DoSuperMethod(cl,obj,MUIM_SpeedBar_GetObject,button);
set(o,tag = msg->tag,value = msg->value);
if (msg->remember)
{
register struct special *specials = data->specials;
switch (tag)
{
case MUIA_Disabled:
if (value) specials[button].flags |= SFLG_Disabled;
else specials[button].flags &= ~SFLG_Disabled;
break;
default:
break;
}
}
return 1;
}
/***********************************************************************/
/*
** Bar Class MUIM_Bar_Disabled method
*/
static ASM ULONG
mBarDisable(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct MUIP_Bar_Disable *msg)
{
register struct data *data = INST_DATA(cl,obj);
register ULONG disable = msg->disable;
if (!BOOLSAME(data->flags & FLG_Disabled,disable))
{
register struct special *specials = data->specials;
register ULONG nb = data->nb;
register int i;
for (i = 0; i<nb; i++)
{
register Object *o;
if (specials[i].flags & SFLG_Skip) continue;
o = (Object *)DoSuperMethod(cl,obj,MUIM_SpeedBar_GetObject,i);
if (disable)
{
ULONG dis;
get(o,MUIA_Disabled,&dis);
if (dis) specials[i].flags |= SFLG_Disabled;
else specials[i].flags &= ~SFLG_Disabled;
set(o,MUIA_Disabled,TRUE);
}
else set(o,MUIA_Disabled,specials[i].flags & SFLG_Disabled);
}
if (disable) data->flags |= FLG_Disabled;
else data->flags &= ~FLG_Disabled;
}
return 0;
}
/***********************************************************************/
/*
** Bar Class MUIM_Bar_Notify method
*/
static ASM ULONG
mBarNotify(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct MUIP_Bar_Notify *msg)
{
register struct data *data = INST_DATA(cl,obj);
register ULONG button = msg->button, res;
if (button>=data->nb) return 0;
msg->button = MUIM_Notify;
res = DoMethodA((Object *)DoSuperMethod(cl,obj,MUIM_SpeedBar_GetObject,button),(Msg)&msg->button);
msg->button = button;
return res;
}
/***********************************************************************/
/*
** Bar Class MUIM_Bar_Active method
*/
static ASM ULONG
mBarActive(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct MUIP_Bar_Active *msg)
{
return nfset(obj,MUIA_Bar_Active,msg->button);
}
/***********************************************************************/
/*
** Bar Class dispatcher
*/
static ULONG SAVEDS ASM
dispatcher(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
{
switch(msg->MethodID)
{
case OM_NEW: return mNew(cl,obj,(APTR)msg);
case OM_GET: return mGet(cl,obj,(APTR)msg);
case OM_SET: return mSets(cl,obj,(APTR)msg);
case OM_DISPOSE: return mDispose(cl,obj,(APTR)msg);
case MUIM_Bar_Set: return mBarSet(cl,obj,(APTR)msg);
case MUIM_Bar_Notify: return mBarNotify(cl,obj,(APTR)msg);
case MUIM_Bar_Disable: return mBarDisable(cl,obj,(APTR)msg);
case MUIM_Bar_Active: return mBarActive(cl,obj,(APTR)msg);
default: return DoSuperMethodA(cl,obj,msg);
}
}
/***********************************************************************/
/*
** Bar Class create
*/
BOOL ASM
createBarClass(REG(a0) struct MUI_CustomClass **class)
{
return (BOOL)(*class = MUI_CreateCustomClass(NULL,MUIC_SpeedBar,NULL,sizeof(struct data),dispatcher));
}
/***********************************************************************/
/*
** Bar Class delete
*/
void ASM
deleteBarClass(REG(a0) struct MUI_CustomClass **class)
{
MUI_DeleteCustomClass(*class);
}
/***********************************************************************/